對應《30天挑戰精通 PowerShell》一書的第 12 章
今天來深入探討如何在 PowerShell 中進行篩選和比較,使其能更有效地處理資料。透過理解篩選技巧和比較運算子的使用,將能夠從大量的資訊中快速擷取出有用的內容,提升工作效率。
在處理大量資料時,取得過多的資訊可能會讓人不知所措。PowerShell 提供了兩種通用的模型來精簡結果,兩種方法都稱為篩選( filtering )。
透過 cmdlet 本身提供的 Parameter 去篩選出你指定的內容,舉例,當我們執行 Get-ChildItem 時,可以透過 -Name 去 filter 出包含檔案名稱包含 txt 字眼,換句話說,嘗試指示「擷取資訊的 cmdlet 」只擷取「你指定的內容」。
# Gets the items and child items in one or more specified locations.
PS /Users/kanglin/code/30days> Get-ChildItem
    Directory: /Users/kanglin/code/30days
UnixMode         User Group         LastWriteTime         Size Name
--------         ---- -----         -------------         ---- ----
-rw-r--r--    kanglin staff       2024/9/24 22:14           63 aliases.txt
-rw-r--r--    kanglin staff       2024/9/24 13:09           90 modules.txt
-rw-r--r--    kanglin staff       2024/9/26 10:43        29233 result.json
-rw-r--r--    kanglin staff       2024/9/26 10:47         2943 Untitled.ipynb
PS /Users/kanglin/code/30days> Get-ChildItem -Name *.txt
aliases.txt
modules.txt
透過 pipeline,迭代式的先接收第一組 cmdlet 提供的內容後,再使用第二組 cmdlet( Where-Object )在管線中篩選物件。
# 列出系統中使用 CPU 時間超過一定值的 Process。
PS /Users/kanglin/code/30days> Get-Process | Where-Object { $_.CPU -gt 100 }
 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00      75.03     517.71   24419   1 Anytype
      0     0.00      30.06     349.13   24420   1 Anytype Helper
      0     0.00     131.83   1,582.31   24423   1 Anytype Helper
      0     0.00      92.77     749.49   24422   1 anytypeHelper
      0     0.00      15.08     272.49   24106   1 AXVisualSupport
      0     0.00     125.48     764.37   24428   1 ChatGPT
      0     0.00      14.84     377.43   25076   1 Code Helper (GP
      0     0.00      26.41     138.41   24088   1 ControlCenter
      0     0.00      21.20     324.91   24096   1 corespeechd
      0     0.00      22.70     105.63   24394   1 CursorUIViewSer
      0     0.00      29.98     162.85   41705   1 Easydict
      0     0.00      38.78     181.01   25070   1 Electron
      0     0.00      10.38     107.72   24138   1 fileproviderd
      0     0.00      42.23     176.45   24102   1 Finder
      0     0.00     155.28   1,614.23   24576   1 Google Chrome
Where-Object 用於篩選物件。$_. 代表管線中當前的物件。-eq 是比較運算子,表示「等於」。將篩選條件儘早應用,能夠提升命令的執行效率。這被稱為「篩選左移」,意思是在管線的左側盡可能地進行篩選。
篩選左移這個技術的缺點在於,每個 cmdlet 都可以實作自己的特定篩選方式,而且每個 cmdlet 在執行篩選的能力亦有所差異。
然後當無法透過單一 cmdlet 本身所提供的第一種 Filter 方式時,我們轉而使用第二種方式,透過 Where-Object 來篩選,而這個篩選的過程則需要用到比較運算式( comparison operator )。
在電腦領域中,「比較」就是要把兩個物件或值拿來判斷彼此之間的關係。
透過使用「比較運算子」來指明你想要判斷的關係種類。在簡單的判斷中,結果會是一個布林值( Boolean value ):True 或 False。換言之,判斷出來的關係要嘛是你所指定的那樣,要嘛不是。
PowerShell 提供了一系列的比較運算子,用於比較數值、字串和模式。
-eq:等於-ne:不等於-gt:大於-lt:小於-like:匹配字串模式(支援萬用字元)-match:正則表達式匹配而想要一次比較多項條件時,可使用邏輯運算子( logical operator )
-and :邏輯「和」。只有當兩個子運算式都為** True** 時,結果才為** True**。(5 -gt 10) -and (10 -qt 100)
# 第一個子運算式:5 -gt 10,即 5 是否大於 10,結果為 False。
# 第二個子運算式:10 -lt 100,即 10 是否小於 100,結果為 True。
# 整體運算式:False -and True,因為 -and 需要兩個子運算式都為 True,所以結果為 False。
-or :邏輯「或」。只要有一個子運算式為** True**,結果就為** True**。(5 -gt 10) -or (10 -lt 100)
# 第一個子運算式:5 -gt 10,結果為 False。
# 第二個子運算式:10 -lt 100,結果為 True。
# 整體運算式:False -or True,因為 -or 只要有一個子運算式為 True,結果就為 True。
-not :邏輯「非」。將布林值取反**,True** 變** False,False** 變** True**。如果您想要列出所有 不 以 “Win” 開頭的服務:
Get-Service | Where-Object { -not ($_.Name -like 'Win*') }
在使用 PowerShell 進行篩選和比較時,可能會遇到一些常見的困惑點。
為什麼要優先在左側進行篩選?
不優化的篩選
Get-Service | Where-Object { $_.Status -eq 'Stopped' }
優化的篩選
Get-Service -Status Stopped
Day 14 - 遠端控制:一對一及一對多